;♖ ♘ ♗ ♔ ♕ ♗ ♘ ♖
;♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
;⬛ ⬜ ⬛ ⬜ ⬛ ⬜ ⬛ ⬜
;⬛ ⬜ ⬛ ⬜ ⬛ ⬜ ⬛ ⬜
;⬛ ⬜ ⬛ ⬜ ⬛ ⬜ ⬛ ⬜
;⬛ ⬜ ⬛ ⬜ ⬛ ⬜ ⬛ ⬜
;♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟
;♜ ♞ ♝ ♚ ♛ ♝ ♞ ♜
;✓✗

BITS 16

%include "macrosmodoreal.mac"

%define KORG 0x1200

global start
extern tsss
extern gdt
extern GDT_DESC
extern IDT_DESC
extern inicializar_idt


extern inicializar_mmu
extern inicializar_dir_kernel
extern page_dir
extern kprintf

extern extender_dir_kernel

extern inicializar_dir_usuario
extern mapear_pagina
extern unmapear_pagina

extern deshabilitar_pic
extern resetear_pic
extern habilitar_pic

extern cargar_tarea


;Aca arranca todo, en el primer byte.
start:

		cli			;no me interrumpan por ahora
		jmp 	bienvenida

;aca ponemos todos los mensajes		
iniciando: db 'Iniciando el kernel del TP'
iniciando_len equ $ - iniciando
escribefila26colu1: db 'X',0
banda_PEnabled: db 'Scorpions',0
banda_PEnabled_len: equ $ - banda_PEnabled


bienvenida:

		IMPRIMIR_MODO_REAL iniciando, iniciando_len, 0x07, 0, 0
		
		;Habilitar A20
		call	checkear_A20
		call 	habilitar_A20
		call	checkear_A20
		
			
		;
		; Ejercicio 1:
		; - Completar GDT  ✓
		; - Pasar a MP     ✓
		; - Pintar pantalla de negro y hacer recuadro ✓
		

		lgdt 	[GDT_DESC]	;cargo GDT definida en .c
		mov eax, cr0		;cargo el  cr0
		or ax, 1			;habilito modo protegido
		mov cr0, eax		;guardo el cr0

		jmp 0x08:modo_protegido	;empieza modo protegido!

BITS 32
modo_protegido:

			;paso todo al seg de datos principal
			mov 	eax, 0x10	
			mov 	ds, ax		
			mov 	es, ax		
			mov 	fs, ax		
			mov 	gs, ax		
			mov 	ss, ax	

			;preparo para escribir en el segmento de video
				mov ax, 0x18	
				mov es, ax
				xor edi,edi
				;edi =  offset de es:edi

			;limpio la pantalla 
			mov ecx, 2000 ;25 * 80 = 2000 tamanio pantalla
			xor eax, eax		;par de bytes en negro

	clean:
		stosw			;escribe un byte engro en es:edi y sigue
		loop clean

	;ahora las lineas azules...
	xor edi,edi			
	mov eax,1000h		;preparo  a dibujar en azul

	mov ecx,80
	add edi,160  ;me salteo una fila (80 es el tamaño, y son 2 bytes x celda..)
	
	linea1:
		stosw
		loop linea1
	
	add edi, 3360 ;21*80*2, me salteo 21 filas
	mov ecx,80    		
	linea2:
		stosw
		loop linea2

	; ------PREGUNTA 1
	;--- escribe fila 25, columna 80
	;push dword 79
	;push dword 24
	;push dword 0xA
	;push dword escribefila26colu1
	;call kprintf
	;--- escribe fila 26, columna 1
	;add esp, 16
	;push dword 0
	;push dword 25
	;push dword 0xA
	;push dword escribefila26colu1
	;call kprintf
	;add esp, 16	
	;jmp $
	; ------fin PREGUNTA 1

		; Ejercicio 2
		; - crear idt para excepciones
		; - generar excepcion
	
	
	lidt[IDT_DESC]
	call inicializar_idt
	

		; Ejercicio 3
		
		; - inicializar la mmu
	call inicializar_mmu
		
		; - inicializar el directorio de paginas del kernel h 4mb
	call inicializar_dir_kernel
	
		; - habilitar paginacion
	mov eax, [page_dir]
	mov cr3, eax		;carga ubicacion del directorio
		
	mov eax, cr0
	or eax, 0x80000000
	mov cr0, eax		; PG = 1
	
		; - imprimir mensaje

	push dword 1
	push dword 0
	push dword 0x7
	push dword banda_PEnabled
	call kprintf
	add esp, 16
	
	
	;mov [0x01FF0010], dword 0xfedcba98	
	
	
		; - habilitar paginas de 4 mb
	mov eax, cr4
	or eax, 0x00000010
	mov cr4, eax
	
		; - modificar el directorio de p'aginas para mapear h 64mb usando paginas de 4mb
	call extender_dir_kernel
	
		; - TODO: ALGO PARA PROBAR QUE ANDA
	mov [0x01000010], dword 0xfedcba98	
	
		; Ejercicio 4:
		; - inicializar_dir_usuario
		
	call inicializar_dir_usuario	
	
	mov ebx,eax
		
	
	; - mapear_pagina
	push 3
	push 0x000B8000
	push eax
	push 0x1F040000
	call mapear_pagina
	add esp, 16
	
	
	; - intercambiar dir	
	mov eax,ebx
	mov cr3, eax		;carga ubicacion del nuevo directorio
	

	; - pintar primer linea
	mov eax,0x10
	mov es,eax
	mov edi, 0x1F040000
	mov eax,0x2F		;
	mov ecx,80
	
	linea4:
		inc edi
		stosb
		
		loop linea4

	; - volver a intercambiar
	mov eax, cr3
	mov ebx, eax		;ebx = ubicacion del directorio de usuario
	
	mov eax, [page_dir]
	mov cr3, eax	
	
	; - unmapear
	push ebx
	push 0x1F040000
	call unmapear_pagina
	add esp, 8
	
		; Ejercicio 5
		; - completar IDT 88 y 89 ✓
	
		; - completar IDT reloj y teclado ✓

		; - habilitar pic e interrupciones para probar.
		call deshabilitar_pic
		call resetear_pic
		call habilitar_pic		
		
		;~ sti
		

	
	
	
		; Ejercicio 6
		; - cargar_tarea	
	
	; creo TSS para que el kernel tenga donde guardar el contexto
	mov eax, tsss
	mov DWORD [eax + 4], esp  ; esp0 = esp
	mov  WORD [eax + 8], 0x10 ; ss0 = Sel Datos nivel 0
	mov ebx, cr3
	mov DWORD [eax + 28], ebx
	mov WORD [eax + 0x64], 0xFFFF

	; defino descriptor
	mov WORD [gdt+6*8+0], 103 ; Limit = 104
	mov DWORD [gdt+6*8+4], eax ; Base_24_31
	mov DWORD [gdt+6*8+2], eax ; Base_0_15 y 16_23
	mov WORD [gdt+6*8+5], 0x0089; ATTR+TYPE	
	


	
	mov ax, 6*8
	ltr ax    		  ; Carga el selector de TSS en el Task Register	
	
;CARGO TAREA 1
	push 0x000000001
	push 0x000010000
	call cargar_tarea
	add esp, 8
		
;CARGO TAREA 2
	push 0x000000002
	push 0x000012000
	call cargar_tarea
	add esp, 8

;CARGO TAREA 3
	push 0x000000003
	push 0x000014000
	call cargar_tarea
	add esp, 8

;CARGO TAREA 4
	push 0x000000004
	push 0x000016000
	call cargar_tarea
	add esp, 8
	
	; - saltar a la tarea 1
	jmp 0x38:0
	



	; - modificar ISR reloj para que cambie de tarea	 ✓
	
	jmp $		
		
%include "a20.asm"

TIMES 0x2000 - KORG - ($ - $$) db 0x0

